package service

import (
	"crypto/md5"
	"database/sql"
	"encoding/hex"
	"errors"
	"go-web-app-demo/common"
	"go-web-app-demo/dao/db"
	"go-web-app-demo/model"
	"go-web-app-demo/pkg/jwt"
	"go-web-app-demo/pkg/snowflake"
	"go.uber.org/zap"
	"strings"
)

func SignUp(s *model.SignUpRequest) *common.Result {

	zap.L().Info("用户注册", zap.Reflect("参数", s))

	exists, _ := checkUserExists(s.Username)
	if exists {
		return common.NewFailed("用户名已存在")
	}

	u := &db.User{
		UserID:   uint64(snowflake.NextID()),
		Username: s.Username,
		Password: encrypt(s.Password),
	}
	if err := db.NewUser(u); err != nil {
		return common.NewFailed(err.Error())
	}

	return common.NewSucceed(u)
}

func Login(s *model.LoginRequest) *common.Result {

	u, err := db.GetByUsername(s.Username)

	if err != nil {
		return common.NewFailed(err.Error())
	}

	if errors.Is(err, sql.ErrNoRows) {
		zap.L().Warn("用户不存在", zap.String("username", s.Username))
		return common.NewFailed("用户名不存在")
	}

	if encrypt(s.Password) != u.Password {
		return common.NewFailed("用户名密码错误")
	}

	token, err := jwt.GenToken(u.UserID, u.Username)

	if err != nil {
		return common.NewFailed(err.Error())
	}

	return common.NewSucceed(token)

}

func checkUserExists(un string) (bool, error) {
	count, err := db.CountByUsername(un)
	return count > 0, err
}

func encrypt(v string) string {
	h := md5.New()
	h.Write([]byte(strings.ToUpper(v)))
	return hex.EncodeToString(h.Sum([]byte(v)))
}
